using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Skinner
{
    public partial class InfoPopup : Form
    {
        private InfoPopup()
        {
            InitializeComponent();
        }

        SkinnerMain _mainForm = null;
        EventHandler _focusHandler = null;
        HtmlElement _activeElement = null;

        private enum InspectModeEnum
        {
            ActiveElement,
            MouseOver
        }

        InspectModeEnum _inspectMode = InspectModeEnum.ActiveElement;

        public InfoPopup(SkinnerMain mainForm)
        {
            InitializeComponent();
            _mainForm = mainForm;
            
            _focusHandler = new EventHandler(browser_HtmlDocument_Focus);
            _mainForm.browser.Document.AttachEventHandler("onactivate", _focusHandler);

            _mainForm.browser.Document.MouseOver += new HtmlElementEventHandler(browser_HtmlDocument_MouseOver);
            _mainForm.browser.Document.MouseDown += new HtmlElementEventHandler(browser_HtmlDocument_MouseDown);

            this.TopMost = true;
        }

        private bool _lock = false;

        void browser_HtmlDocument_MouseDown(object sender, HtmlElementEventArgs e)
        {
            if (e.MouseButtonsPressed == MouseButtons.Left && _inspectMode == InspectModeEnum.MouseOver)
            {
                _lock = !_lock;
            }
            e.BubbleEvent = true;
        }

        private void browser_HtmlDocument_Focus(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.Print("In Activate");
            if (_inspectMode == InspectModeEnum.ActiveElement)
            {
                _activeElement = _mainForm.browser.Document.ActiveElement;
                mshtml.IHTMLElement element = (mshtml.IHTMLElement)_activeElement.DomElement;
                txtID.Text = (element.id==null?string.Empty:element.id);

                ClearPanel();
                AddClassLinks(element);

                txtStyles.Text = (_mainForm.browser.Document.ActiveElement.Style==null?string.Empty:_mainForm.browser.Document.ActiveElement.Style);
                txtHTML.Text = element.outerHTML;
            }
        }

        private void browser_HtmlDocument_MouseOver(object sender, System.Windows.Forms.HtmlElementEventArgs e)
        {
            Object thisLock = new Object();
            lock(thisLock)
            {
                if (!_lock)
                {
                    System.Diagnostics.Debug.Print("In MouseOver");
                    
                    if (_inspectMode == InspectModeEnum.MouseOver)
                    {
                        System.Diagnostics.Debug.Print(string.Format("{0}, {1}", e.MousePosition.X, e.MousePosition.Y));
                        _activeElement = _mainForm.browser.Document.GetElementFromPoint(e.MousePosition);
                        mshtml.IHTMLElement element = (mshtml.IHTMLElement)_activeElement.DomElement;
                        txtID.Text = element.id;

                        ClearPanel();
                        AddClassLinks(element);

                        txtStyles.Text = _mainForm.browser.Document.GetElementFromPoint(e.MousePosition).Style;
                        txtHTML.Text = element.outerHTML;
                    }
                }
            }
        }

        private void InfoPopup_FormClosing(object sender, FormClosingEventArgs e)
        {
            _mainForm.browser.Document.MouseOver -= new HtmlElementEventHandler(browser_HtmlDocument_MouseOver);
            _mainForm.browser.Document.MouseDown -= new HtmlElementEventHandler(browser_HtmlDocument_MouseDown);
            if (_focusHandler != null)
                _mainForm.browser.Document.DetachEventHandler("onactivate", _focusHandler);
            _mainForm = null;
        }

        private void activeElementToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _inspectMode = InspectModeEnum.ActiveElement;
            activeElementToolStripMenuItem.Checked = true;
            mouseOverToolStripMenuItem.Checked = false;
        }

        private void mouseOverToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _inspectMode = InspectModeEnum.MouseOver;
            activeElementToolStripMenuItem.Checked = false;
            mouseOverToolStripMenuItem.Checked = true;
        }

        private void AddClassLinks(mshtml.IHTMLElement element)
        {
            int height = 20;
            int topPad = 1;
            int leftPad = 5;
            int topOffset = 0;

            int position = 0;

            mshtml.IHTMLElement currentElement = element;
            do
	        {
                if (currentElement.className != null && currentElement.className != string.Empty)
                {
                    LinkLabel label = new LinkLabel();
                    label.Text = "." + currentElement.className;
                    label.AutoSize = true;
                    label.Location = new Point(leftPad, ((topPad * position) == 0 ? topPad + topOffset : (topPad * (position + 1)) + (height * position) + topOffset));
                    position++;
                    label.Click += new EventHandler(classLabel_Click);
                    classPanel.Controls.Add(label);
                }
                currentElement = currentElement.parentElement;
            } while (currentElement != null);
        }

        private void ClearPanel()
        {
            foreach(Control c in classPanel.Controls)
            {
                if (c is LinkLabel)
                {
                    ((LinkLabel)c).Click -= new EventHandler(classLabel_Click);
                }
            }
            classPanel.Controls.Clear();
        }

        void classLabel_Click(object sender, EventArgs e)
        {
            if (_activeElement == null || _mainForm.SelectedSheet == null)
            {
                return;
            }
            string matchClass = StyleSheet.GetMatchingStyle(((LinkLabel)sender).Text, _activeElement, _mainForm.SelectedSheet);

            if (matchClass == string.Empty)
            {
                if (MessageBox.Show("No matching style was found in the selected style sheet.\nDo you wish to add it?", "Not Found", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    matchClass = ((LinkLabel)sender).Text;
                    _mainForm.SelectedSheet.Sheet.addRule(matchClass, " ", _mainForm.SelectedSheet.Sheet.rules.length);
                    _mainForm.SelectedSheet.Rules.Add(matchClass.ToUpper(), new StyleRule(_mainForm.SelectedSheet.Sheet.rules.item(_mainForm.SelectedSheet.Sheet.rules.length - 1), _mainForm.SelectedSheet));
                }
                else
                    return;
            }

            StyleEdit editForm = new StyleEdit(_mainForm.SelectedSheet.Rules[matchClass.ToUpper()]);
            editForm.Show();
        }
    }
}